package com.likan.chqjtgc;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.likan.chqjtgc.enums.HttpStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lxh
 * @date 2018/2/2
 */
@Slf4j
@Configuration
@EnableResourceServer
//开启基于方法的声明式权限控制
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    /**
     * 项目启动时，获取项目名称 spring.applicaion.name, 用于设置鉴权资源服务器的id  此处配置 应该和auth模块的 resourceIds的配置一致
     */
    @Value("${spring.application.name}")
    private String applicationName;

    @Autowired
    private ResourceServerTokenServices tokenService;

    //放行接口
    private static final String[] AUTH_WHITELIST = {

            // -- swagger ui
            "/swagger-resources/**",
            "/swagger-ui.html",
            "/v2/api-docs",
            "/webjars/**",
            "/logout/**",
            //业务放行接口
            //资源下载
            "/file/download/**",
            //登陆,必须放行
            "/login/**"
    };


    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
//                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//                .and()
//                .authorizeRequests().anyRequest().permitAll().and().logout().permitAll()
//                .and()
                .exceptionHandling()
                .authenticationEntryPoint((request, response, authException) -> {
                    Map<String,String> map = new HashMap<>();
                    map.put("code", String.valueOf(HttpStatus.UNAUTHORIZED.value()));
                    map.put("message", "登陆已过期，请重新登陆");
                    map.put("timestamp", String.valueOf(System.currentTimeMillis()));
                    response.setContentType("application/json;charset=UTF-8");
                    response.setHeader("Access-Control-Allow-Origin","*");
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    try {
                        response.getOutputStream().write(new ObjectMapper().writeValueAsString(map).getBytes());
                    } catch (Exception e) {
                        throw new ServletException();
                    }
                })
                .and()
                .authorizeRequests().antMatchers(AUTH_WHITELIST).permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic().disable();

    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources
                //重点，设置资源id  访问每个模块的id 此id标识是否具有访问该模块的权限
                .resourceId(applicationName)
                .tokenServices(tokenService);
    }





}
